package com.tiancheng.trade.authserver.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiancheng.trade.authserver.entity.AuthPermission;
import com.tiancheng.trade.authserver.entity.AuthRole;
import com.tiancheng.trade.authserver.entity.AuthRoleMapPermission;
import com.tiancheng.trade.authserver.mapper.AuthRoleMapPermissionMapper;
import com.tiancheng.trade.authserver.service.IAuthPermissionService;
import com.tiancheng.trade.authserver.service.IAuthRoleMapPermissionService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuthRoleMapPermissionServiceImpl extends ServiceImpl<AuthRoleMapPermissionMapper, AuthRoleMapPermission> implements IAuthRoleMapPermissionService {
    @Resource
    private IAuthPermissionService permissionService;


    @Override
    public void removeRolePermission(Long roleId) {
        this.remove(new LambdaQueryWrapper<AuthRoleMapPermission>().eq(AuthRoleMapPermission::getRoleId,roleId));
    }

    @Override
    public void removeByPermissionId(Long permissionId) {
        this.remove(new LambdaQueryWrapper<AuthRoleMapPermission>().eq(AuthRoleMapPermission::getPermissionId,permissionId));

    }

    @Override
    public void saveRoleMapPermission(AuthRole role, Set<AuthPermission> permissions) {

        if (permissions == null) {
            permissions = new HashSet<>();
        }
        permissions.forEach(rolePermission -> {
            if (!rolePermission.getApplicationId().toString().equals(role.getApplicationId())) {
                throw new RuntimeException( "你不能添加其它应用下的权限给本应用下的角色");
            }
        });
        List<AuthRoleMapPermission> oldRMPs = this.getByRoleId(role.getId());
        final Map<Long, List<AuthPermission>> oldPermissions = this.permissionService.list(new LambdaQueryWrapper<AuthPermission>().in(AuthPermission::getId, oldRMPs.stream().map(AuthRoleMapPermission::getPermissionId).collect(Collectors.toSet())))
                .stream().collect(Collectors.groupingBy(AuthPermission::getId));

        List<AuthRoleMapPermission> roleMapPermissions = new LinkedList<>();
        for (AuthPermission permission : permissions) {
            //如果老权限列表不包含新的权限
            if (!oldPermissions.containsKey(permission.getId())) {
//                if (!sessionSubject.isPermitted(permission.getDataPermissionCode())) {
//                    throw new RuntimeException("你无权给该角色添加名称为:'" + permission.getName() + "'的权限");
//                }
            }
            AuthRoleMapPermission roleMapPermission = new AuthRoleMapPermission();
            roleMapPermission.setPermissionId(permission.getId());
            roleMapPermission.setRoleId(role.getId());
            roleMapPermissions.add(roleMapPermission);
        }
        for (List<AuthPermission> permissions1 : oldPermissions.values()) {
            for (AuthPermission permission : permissions1) {
                if (!permissions.contains(permission)) {
//                    if (!sessionSubject.isPermitted(permission.getDataPermissionCode())) {
//                        throw new RuntimeException( "你无权删除该角色名称为:'" + permission.getName() + "'的权限");
//                    }
                }
            }
        }
        this.removeRolePermission(role.getId());
        this.saveBatch(roleMapPermissions);
    }

    @Override
    public void addRoleMapPermission(AuthRole role, AuthPermission permission) {
        if (!role.getApplicationId().equals(permission.getApplicationId())) {
            throw new RuntimeException("你不能添加其它应用下的权限给本应用下的角色");
        }
        if (this.getByRoleIdAndPermissionId(role.getId(), permission.getId()) == null) {
            AuthRoleMapPermission roleMapPermission = new AuthRoleMapPermission();
            roleMapPermission.setPermissionId(permission.getId());
            roleMapPermission.setRoleId(role.getId());
            this.save(roleMapPermission);
        }
    }

    @Override
    public List<AuthRoleMapPermission> getByRoleId(Long roleId) {
        return this.list(new LambdaQueryWrapper<AuthRoleMapPermission>().eq(AuthRoleMapPermission::getRoleId,roleId));
    }

    @Override
    public AuthRoleMapPermission getByRoleIdAndPermissionId(Long roleId, Long permissionId) {

        List<AuthRoleMapPermission> exPermissions = this.list(new LambdaQueryWrapper<AuthRoleMapPermission>().eq(AuthRoleMapPermission::getRoleId,roleId)
                .eq(AuthRoleMapPermission::getPermissionId,permissionId));
        if (exPermissions != null && !exPermissions.isEmpty()) {
            return exPermissions.get(0);
        }
        return null;
    }

    @Override
    public Map<Long, AuthRoleMapPermission> getByIds(Set<Long> ids) {
        Map<Long, AuthRoleMapPermission> result = new HashMap<>();
        if (ids != null && !ids.isEmpty()) {
            List<AuthRoleMapPermission> rMPs = this.list(new LambdaQueryWrapper<AuthRoleMapPermission>().in(AuthRoleMapPermission::getId,ids));
            if (rMPs != null) {
                rMPs.forEach(rMP -> {
                    result.put(rMP.getId(), rMP);
                });
            }
        }
        return result;
    }

    @Override
    public Map<String, AuthRoleMapPermission> getRIdPIdMapRPByRoleIds(Set<Long> roleIds) {
        Map<String, AuthRoleMapPermission> result = new HashMap<>();
        if (roleIds != null && !roleIds.isEmpty()) {
            List<AuthRoleMapPermission> rMPs = this.list(new LambdaQueryWrapper<AuthRoleMapPermission>().in(AuthRoleMapPermission::getRoleId,roleIds));
            if (rMPs != null) {
                rMPs.forEach(rMP -> {
                    result.put(rMP.getRoleId() + ":" + rMP.getPermissionId(), rMP);
                });
            }
        }
        return result;
    }
}
